package com.aca.market.Realm;

import com.aca.market.entity.User;
import com.aca.market.service.IPermissionService;
import com.aca.market.service.IUserService;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import lombok.extern.slf4j.Slf4j;
import org.apache.shiro.SecurityUtils;
import org.apache.shiro.authc.*;
import org.apache.shiro.authz.AuthorizationInfo;
import org.apache.shiro.authz.SimpleAuthorizationInfo;
import org.apache.shiro.realm.AuthorizingRealm;
import org.apache.shiro.subject.PrincipalCollection;
import org.apache.shiro.subject.Subject;
import org.apache.shiro.util.ByteSource;
import org.springframework.beans.BeansException;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.context.ApplicationContextAware;

import java.util.List;

//@Lazy(false)
@Slf4j
public class UserRealm extends AuthorizingRealm implements ApplicationContextAware {

    private static ApplicationContext context;

    @Autowired
    IUserService userService;

    @Autowired
    IPermissionService permissionService;


    @Override
    protected AuthorizationInfo doGetAuthorizationInfo(PrincipalCollection principals) {
        System.out.println("===========================doGetAuthorizationInfo");

        //区分 authenticate 认证 和 authorize 授权
        //授权
        SimpleAuthorizationInfo authorizationInfo = new SimpleAuthorizationInfo();
        //拿到当前登陆的用户
        Subject subject = SecurityUtils.getSubject();
        //拿到user <- 下面SimpleAuthenticationInfo(user,password,salt,"") 的user
        //pricipal是一个Object，就是我们的带有username属性的实体对象
        User curUser = (User) subject.getPrincipal();
        //找到对应roleId的permission
        permissionService = (IPermissionService) context.getBean("permissionService");
        List<String> permissions = permissionService.getPerms(curUser.getRoleId());

        //数据库里的 传递过来的实体
        //拿角色和权限
        authorizationInfo.addStringPermissions(permissions);
        authorizationInfo.addRoles(permissionService.getUserRoles(permissions));
        return authorizationInfo;
    }


    @Override
    protected AuthenticationInfo doGetAuthenticationInfo(AuthenticationToken authenticationToken) throws AuthenticationException {
        System.out.println("==================>3.doGetAuthenticationInfo");
        //连接数据库
        UsernamePasswordToken token = (UsernamePasswordToken) authenticationToken;
//        System.out.println("===============4.token.getPassword(): "+token.getPassword().toString());
        String username = (String) token.getPrincipal();
        String password = String.valueOf(token.getPassword());
        //盐
        ByteSource salt = ByteSource.Util.bytes(username);
//        //hashlterations 混淆次数
//        SimpleHash pwd = new SimpleHash("MD5",token.getPassword(),salt,1);

        //匹配
        userService = (IUserService) context.getBean("userService");
        User user = userService.getOne(new QueryWrapper<User>()
                .eq("username", username)
                .eq("password",password));
        if (user == null) return null;
        System.out.println("登陆=========USER:" + user.toString());
        //这里的参数没有salt也可以登录
        return new SimpleAuthenticationInfo(user,password,salt,"");
    }

    @Override
    public void setApplicationContext(ApplicationContext applicationContext) throws BeansException {
        context = applicationContext;
    }
}
